package de.breitbeil.jbooking.ui.dataview;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.springframework.context.MessageSource;
import org.springframework.richclient.application.ApplicationServicesLocator;

import ca.odell.glazedlists.Filterator;
import ca.odell.glazedlists.TextFilterator;
import ca.odell.glazedlists.impl.beans.BeanProperty;

public class I8nTextFilterator<D,E> implements TextFilterator<E>, Filterator<D,E> {

	private MessageSource messageSource;
	
	private List<String> i18nPropertyNames;
	
    /** Java Beans property names */
    private List<String> propertyNames;

    /** methods for extracting field values */
    private List<BeanProperty> beanProperties = null;
	
	public I8nTextFilterator(List<String> propertyNames, List<String> i18nPropertyNames) {
		this.propertyNames = propertyNames;
		this.i18nPropertyNames = i18nPropertyNames;
		
		messageSource = (MessageSource)ApplicationServicesLocator.services().getService(MessageSource.class);
	}
	
    /** {@inheritDoc} */
    public void getFilterStrings(List<String> baseList, E element) {
        if(element == null) return;

        // load the property descriptors on first request
        if(beanProperties == null) loadPropertyDescriptors(element);

        // get the filter strings
        for(BeanProperty<E> property: beanProperties) {
            Object propertyValue = property.get(element);
            if(propertyValue == null) continue;
            if(i18nPropertyNames.contains(property.getPropertyName())) {
            	propertyValue = getMessage((String)propertyValue+".label");
            }
            baseList.add(propertyValue.toString());
        }
    }

    /** {@inheritDoc} */
    public void getFilterValues(List<D> baseList, E element) {
        if(element == null) return;

        // load the property descriptors on first request
        if(beanProperties == null) loadPropertyDescriptors(element);

        // get the filter strings
        for(BeanProperty<E> property: beanProperties) {
            Object propertyValue = property.get(element);
            if(propertyValue == null) continue;
            if(i18nPropertyNames.contains(property.getPropertyName())) {
            	propertyValue = getMessage((String)propertyValue+".label");
            }
            baseList.add((D)propertyValue);
        }
    }

    /**
     * Loads the property descriptors which are used to invoke property
     * access methods using the property names.
     */
    private void loadPropertyDescriptors(E beanObject) {
        Class<E> beanClass = (Class<E>) beanObject.getClass();
        beanProperties = new ArrayList<BeanProperty>();
        for(String property: propertyNames) {
            beanProperties.add( new BeanProperty<E>(beanClass, property, true, false) );
        }
    }
    
    private String getMessage(String code) {
    	return messageSource.getMessage(code, new Object[0], Locale.getDefault());
    }

}
